﻿package org.abc.uiCore
{
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	
	import org.abc.interfaces.ICommand;
	import org.abc.interfaces.IEventVo;
	import org.abc.uiCore.vo.EventVo;

	/**
	 * 负责事件的发送和侦听
	 * @author aisi
	 *
	 */
	public class AbcDispatcher
	{
		/** 事件类型字典 */
		private static var events:Dictionary=new Dictionary();
		/** 逻辑类型字典 */
		private static var commands:Dictionary=new Dictionary();

		/**
		 * 侦听事件
		 * @param type 事件类型
		 * @param fun  响应事件函数
		 */
		public static function addEventListener(type:String, fun:Function=null):void
		{
			events[type]=events[type] || [];
			if (Boolean(fun))
			{
				if (events[type].indexOf(fun) == -1)
					events[type].push(fun);
			}
			else if (!commands[type])
			{
				/** 如果fun==null&&commands[type]==null
				 * 则创建一个方法，该方法根据type生成一个Icommand实例，并执行实例中的execute方法*/
				commands[type]=function(e:IEventVo):void
				{
					var fun:Class=getDefinitionByName(type) as Class;
					var command:ICommand=new fun() as ICommand;
					command.execute(e);
				}
				events[type].push(commands[type]);
			}
		}

		/**
		 * 删除侦听
		 * @param type 	事件类型
		 * @param fun	方法
		 */
		public static function removeEventListener(type:String, fun:Function=null):void
		{
			if (!Boolean(events[type]))
				return;
			var index:int;
			if (Boolean(fun))
			{
				index=events[type].indexOf(fun);
				if (index != -1)
					events[type].splice(index, 1)
			}
			else
			{
				index=events[type].indexOf(commands[type]);
				if (index != -1)
					events[type].splice(index, 1);
				delete commands[type];
			}
		}

		/**
		 * 发送事件
		 * @param type 事件类型
		 * @param data 事件引用的数据
		 * 注意：此处对events[type]做拷贝处理，因为函数执行时数组长度会改变
		 */
		public static function dispatchEvent(type:String, data:Object=null):void
		{
			if (Boolean(events[type]))
			{
				var funs:Array=events[type].concat();
				var vo:EventVo=new EventVo();
				for (var i:int=0; i < funs.length; i++)
				{
					if(data)vo.data=data;
					vo.eventType=type;
					funs[i](vo);
				}
				if (events[type].length == 0)
					delete events[type];
			}
			else
			{
				//throw new Error(type+"对应的command未实现!")
			}
		}

		/**
		 * 检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器。
		 * @param type 事件的类型。
		 * @return Boolean
		 */
		public static function hasEventListener(type:String):Boolean
		{
			return events[type];
		}
	}
}
